package de.homelabs.hlmodules.cms.template.service;

import java.io.Reader;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import de.homelabs.hlmodules.cms.api.template.service.IHLTemplateManager;
import de.homelabs.hlmodules.cms.configuration.service.HLConfigurationManager;
import de.homelabs.hlmodules.cms.enums.HLErrorCode;
import de.homelabs.hlmodules.cms.realm.service.HLRealmService;
import de.homelabs.hlmodules.cms.template.domain.HLTemplate;
import de.homelabs.hlmodules.cms.template.domain.HLTemplateException;

/**
 * Implements a TemplateManager that interacts with the Freemarker Framework.
 * 
 * @author D.Mueller
 * 
 *         singleton
 */
@Service("hlFreeMarkerTemplateManager")
public class HLFreemarkerTemplateManager implements IHLTemplateManager {

	@Autowired
	@Qualifier("hlConfigurationManager")
	private HLConfigurationManager hlConfigManager;

	// Strategy
	//private IHLTemplateImportStrategy importStrategy;

	// List of preLoaded Templates
	private Map<String, HLTemplate> templateList = new HashMap<String, HLTemplate>();

	@Autowired
	@Qualifier("hlRealmService")
	private HLRealmService hlRealmService;

	private @Autowired
	HttpServletRequest request;

	/**
	 * constructor
	 */
	public HLFreemarkerTemplateManager() {
		//importStrategy = new HLTemplateFileSystemLoadingStrategy();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see freemarker.cache.TemplateLoader#findTemplateSource(java.lang.String)
	 */
	public HLTemplate findTemplateSource(String name) throws HLTemplateException {
		// check if template has previously been loaded
		if (this.templateList.containsKey(name)) {
			// simply return template
			return this.templateList.get(name);
		} else {
			// not in list so load

			// get domain name
			String normalizedDomain = hlRealmService
					.getNormalizedDomain(request);
			
			HLTemplate template = null;
			try {
				template = hlConfigManager.getConfigurationByDomain(hlRealmService.getNormalizedDomain(request)).getImportStrategy().findTemplateSource(
					hlConfigManager.getConfigurationByDomain(hlRealmService.getNormalizedDomain(request)), normalizedDomain, name);
			} catch (Exception e){
				//System.out.println(e);
			}
			if (template != null)
				this.templateList.put(name, template);
			
			return template;
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see freemarker.cache.TemplateLoader#getLastModified(java.lang.Object)
	 */
	public long getLastModified(HLTemplate templateSource) throws HLTemplateException{
		// only HLTemplates
		if (!(templateSource instanceof HLTemplate)) {
			throw new HLTemplateException(HLErrorCode.UNSUPPORTED_CLASS);
		}
		return hlConfigManager.getConfigurationByDomain(hlRealmService.getNormalizedDomain(request)).getImportStrategy().getLastModified((HLTemplate) templateSource);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see freemarker.cache.TemplateLoader#getReader(java.lang.Object,
	 * java.lang.String)
	 */
	public Reader getReader(HLTemplate templateSource, String encoding)
			throws HLTemplateException {

		// Test for HLTemplate
		if (templateSource instanceof HLTemplate) {
			// return with call from strategy
			return hlConfigManager.getConfigurationByDomain(hlRealmService.getNormalizedDomain(request)).getImportStrategy().getReader((HLTemplate) templateSource,
					encoding);
		} else {
			throw new HLTemplateException(HLErrorCode.UNSUPPORTED_CLASS);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * freemarker.cache.TemplateLoader#closeTemplateSource(java.lang.Object)
	 */
	public void closeTemplateSource(HLTemplate templateSource)
			throws HLTemplateException {
		// Test for HLTemplate
		if (templateSource instanceof HLTemplate) {
			hlConfigManager.getConfigurationByDomain(hlRealmService.getNormalizedDomain(request)).getImportStrategy().closeTemplateSource((HLTemplate) templateSource);
		} else {
			// Object is not Support
			throw new HLTemplateException(HLErrorCode.UNSUPPORTED_CLASS);
		}
	}
}